#!/usr/bin/env python
# coding: utf-8

# In[1]:


#Importing PulP solver
from pulp import *


# In[2]:


#Inputing the Demand points
demand_points=['Port of Newcastle','Port of Hedland','Port of Vienna','Port of Mina','Port of Antwerp','Port of Santos','Port of Montreal','Port of Vancouver','Port of Shanghai','Port of Hamburg_Czeck','Port of Alexandria','Port of Marseille','Port of Hamburg_Germany','Port of Budapest','Port of Jawaharlal Nehru','Port of Tanjung Priok','Port of Bandar Abbas','Port of Umm Qasr','Port of Haifa','Port of Gioia Tauro','Port of Nagoya','Port of Aqaba','Port of Busan','Port of Shuwaikh','Port of Beirut','Port of Manzanillo','Port of Rotterdam','Port of Salalah','Port of Gaza','Port of Gdansk','Port of Doha','Port of King Abdul Aziz','Port of Jeddah','Port of Bratislava','Port of Durban','Port of Algeciras','Port of Gothenburg','Port of Latakia','Port of Kaohsiung','Port of Bangkok','Port of Mersin','Port of Jebel Ali','Port of Immingham','Port of New York','Port of Los Angeles','Port of Hodeidah']


# In[3]:


demand_points


# In[4]:


#Inputing the Supply Points
supply_points=['Port of Santos','Sihanoukville','Douala','Port of Shanghai','Puerto Quetzal','Port of Jawaharlal Nehru','Port of Tanjung Priok','Port of Abidjan','Port of Monrovia','Penang Port','Port of Manzanillo','Port of Yangon','Port of Lagos','Port of Manila','Port of  Colombo','Port of Bangkok','Port of Saigon']


# In[5]:


supply_points


# In[6]:


#Inputing the distances
distance = dict(zip(supply_points,[dict(zip(demand_points, [7848,8509,8705,9662,6658,0,6795,10037,1804,7027,7529,6204,7027,8591,9552,10371,9351,9933,7667,6528,11468,8005,13783,9888,7626,7223,6749,8408,6360,7745,9594,9716,8432,8693,4838,5426,7293,7553,12691,11741,7528,9407,6799,6148,8718,8624])),
dict(zip(demand_points, [5153,2875,8430,4867,9893,11506,11102,6764,2542,10262,6351,8034,10262,8316,3279,1215,4543,5125,6321,7321,3431,5897,3069,5080,6371,15762,9984,4256,6126,10978,4800,4908,5326,8418,6668,8332,10526,6536,1978,326,6531,4613,10035,11846,17253,4788])),
dict(zip(demand_points, [9520,8749,7049,8271,5002,10728,7404,10669,11865,5370,5873,4548,5370,6935,8161,8980,7961,8542,6011,4872,12754,6349,12392,8498,5969,7855,5092,7018,5413,5990,8498,8325,6775,7037,3447,3770,5637,5897,11301,10350,9537,8017,5143,6865,9350,7233])),
dict(zip(demand_points, [5140,3701,10444,6882,11907,13268,11673,4956,0,12277,8365,10048,12277,10330,5293,2909,6557,7139,8336,9335,1007,7912,535,7094,8385,6843,11999,6270,7660,12993,6814,6922,7341,10432,8418,10346,12539,8550,597,2872,8546,6627,12049,10547,5688,6802])),
dict(zip(demand_points, [7240,9320,9827,12209,7811,6371,5046,3666,7701,8179,8682,5723,8179,9713,11977,9783,11893,12480,8820,7681,6993,9158,7259,12433,8779,852,7902,10937,8500,8899,12317,12259,9583,9816,10067,6579,8446,8706,8129,9711,8681,11949,7952,3392,2347,10122])),
dict(zip(demand_points, [6956,4445,5619,1589,7082,9552,9614,9428,5293,7451,3540,5224,7451,5505,0,3071,1265,1847,3510,4510,6171,3086,5810,1802,3560,12946 ,7173,1143,3243,8167,1522,1630,2515,5607,4714,5521,7715,3725,4727,3513,3720,1335,7224,9036,10104,1977])),
dict(zip(demand_points, [4176,1666,8109,4660,9572,10371,12104,7279,2909,9842,6030,7714,9842,7995,3071,0,4336,4917,6000,7000,3787,5576,3426,4873,6049,8920,9663,4050,5814,10657,4592,4700,5005,8097,5533,8011,10205,6215,2343,1449,6210,4405,9714,11525,7910,4466])),
dict(zip(demand_points, [10071,9301,6249,8823,4202,4059,6604,9869,12416,4569,5073,3628,4569,6134,8712,9531,8512,9093,5211,4071,13305,5549,12943,9049,5050,7055,4292,7569,4594,5288,9049,8877,5975,6237,3999,2970,4836,5097,11852,10901,5072,8568,4343,6065,8550,6514])),
dict(zip(demand_points, [10445,9674,5854,8206,3807,3735,6203,9446,12790,4174,4678,3352,4174,5621,8095,9905,7895,8477,4816,3676,13679,5154,13317,8432,4774,6632,3897,6952,4138,4894,8432,8259,5580,5842,4372,2575,4441,4702,12226,11275,4677,7951,3948,5672,8126,6119])),
dict(zip(demand_points, [5076,2565,7419,3856,8882,10534,9839,7359,3025,9251,5340,7024,9251,7305,2268,950,3532,4113,5310,6310,3903,4886,3542,4069,5359,9149,8973,3245,5210,9970,3788,3896,4315,7407,5695,7321,9517,5525,2461,1246,5520,3601,9024,9024,8035,3777])),
dict(zip(demand_points, [6715,8542,10679,13061,8663,7223,5899,2814,6843,9031,9534,8209,9031,10565,12946 ,8920,12745,13332,9673,8533,6131,10011,6404,13286,9631,0,8736,11791,8088,9730,12977,13099,10419,10681,10919,7413,9277,9541,7268,8865,9516,12790,8787,4237,1490,10974])),
dict(zip(demand_points, [5759,3249,7543,3942,9007,10827,11538,16896,3998,9375,5464,7148,9375,7428,2354,1875,3618,4199,5434,6434,4876,5010,4514,4155,5483,9884,9098,3331,5215.2,10094,4155,3982,4439,7531,5987,7445,9641,5649,3434,2218,5644,3687,9148,11002,8770.2,3900])),
dict(zip(demand_points, [9819,9048,6700,8570,4653,4510,7055,10321,12164,5021,5524,4198,5021,6586,8460,9279,8260,8841,5662,4523,12403,6000,12691,8797,5620,7506,4744,7317,5052,5740,8797,8624,6426,6688,3746,3421,5287,5548,11600,10649,5523,8316,4794,6516,9001,6965])),
dict(zip(demand_points, [4322,2887,9356,5794,10820,12186,13352,5871,1225,11188,7278,8962,11188,9242,4205,1821,5470,6051,7248,8248,2103,6824,1741,6007,7297,7679,10911,5182,6834,11907,6007,5834,6253,9345,7406,9259,11455,7462,667,1783,7458,5539,10961,12815,6537,5714])),
dict(zip(demand_points, [6013,3503,6118,2531,7582,9361,10113,8562,4350,7950,4039,5723,7950,6004,943,2129,2207,2788,4010,5009,5228,3586,4867,2744,4059,13434,7673,1920,3991,8669,2464,2572,3015,6106,4522,6020,8217,4224,3786,2571,4220,2276,7723,9577,9238,2476])),
dict(zip(demand_points, [5436,3109,8664,5102,10128,11741,12660,7026,2872,10496,6585,8270,10496,8550,3513,1449,4778,5359,6556,7555,3750,6132,3388,5315,6605,8865,10219,4490,6341,11215,5034,5142,5561,8653,6941,8567,10763,6770,2307,0,6766,4847,10269,12081,7730,5022])),
dict(zip(demand_points, [4876,2659,8528,4964,9991,11334,12523,6829,1997,10360,6448,8133,10360,8413,3376,993,4640,5221,6418,7418,2881,5994,2520,5177,6467,15842,10082,4353,6368,11079,4896,5004,5423,8516,6577,8430,10626,6633,1434,870,6628,4709,10133,11986,593,4884]))]))


# In[7]:


distance


# In[8]:


#Inputing the Rubber Demand
rubber_demand=dict(zip(demand_points, [132371.9726,3563803.7770,193473.5393,563724.0000,1061795.5760,117243.0000,2051043.1140,124437.9933,12928279.7100,3664301.6090,14742.0000,4799344.6930,5926637.3740,674667.0000,18202977.7200,2745000.7070,49077.0000,3276.0000,567.0000,655131.1035,28741405.9800,616518.0000,20838307.4000,1022029.4800,9072.0000,991368.0000,324857.1803,63.0000,0.0000,482624.5046,1013103.0000,1745871.4990,135938.5009,1803395.8740,448245.0000,3124044.8760,329903.6786,3591.0000,1675226.3230,6254780.5530,2705325.0850,79443.0000,2731961.7380,18674740.2200,3046117.9890,630.0000]))


# In[9]:


rubber_demand


# In[10]:


#Inputing the Rubber Supply
rubber_supply=dict(zip(supply_points, [1258648.2900,8234049.7510,217343.9060,8784079.7960,3935392.5450,6522791.1570,34239646.0300,3411326.1430,603911.1280,5312726.1900,330881.7674,1946363.3380,1386711.0420,2541650.1950,741564.4317,49185954.9800,25617418.0800])) 


# In[11]:


rubber_supply


# In[12]:


# Set Problem Variables
prob = LpProblem("Transportation", LpMinimize)


# In[13]:


prob


# In[14]:


# Set Problem Variables
routes = [(i,j) for i in supply_points for j in demand_points]


# In[15]:


routes


# In[16]:


# Decision Variables
X = LpVariable.dicts("ShipmentAmount",(supply_points, demand_points),0)


# In[17]:


X


# In[18]:


# Objective Function
prob += sum(X[i][j]*distance[i][j] for (i,j) in routes)


# In[19]:


prob


# In[20]:


# Constraints
for j in demand_points:
    prob += sum(X[i][j] for i in supply_points) >= rubber_demand[j]
    
prob


# In[21]:


# Constraints
for i in supply_points:
    prob += sum(X[i][j] for j in demand_points) == rubber_supply[i]
prob


# In[22]:


prob.solve()

print("Status:", LpStatus[prob.status])

for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)

print("Total kilogram_miles =", value(prob.objective))

